fix gps metadata being stripped from exports (#1165)#1207
Conversation
write_image_with_metadata has three branches for sourcing the original image's metadata: the .rrdata sidecar, kamadak-exif, and rawler. Only the kamadak and rawler branches had GPS-reading code. Opening any image triggers persist_exif_if_missing, which writes a sidecar -- from then on the sidecar branch fires on every export, silently bypassing both GPS code paths. Affects JPEG (as reported) and any RAW the user has opened. Lift GPS reading into two helpers (apply_gps_from_kamadak, apply_gps_from_rawler) and run them at the tail of the function, unconditionally when !strip_gps. The sidecar/kamadak/rawler branches now handle only the non-GPS metadata they always did. Re-read GPS from the source file rather than parsing the lossy display strings stored in the sidecar. Add two regression tests using only existing project deps (tempfile, image, little_exif, kamadak-exif). The first reproduces the bug trigger (real GPS + .rrdata sidecar) and asserts GPS is preserved; the second asserts the strip toggle still works. Bonus: kamadak helper now also writes GPSAltitudeRef -- the rawler branch already did this, added for symmetry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Can confirm this independently on v1.5.8 (Linux) with a real-world case — might be a useful additional data point since it shows the sidecar-path trigger very clearly. Source: JPEG straight from a Samsung Galaxy S22 Ultra (firmware S908BXXSNGZD7), synced via Nextcloud instant upload. Full GPS EXIF block present and verified in the original: [GPS] GPSVersionID : 2.2.0.0 (via exiftool -a -G1 -s file.jpg | grep -i gps — note: plain exiftool -gps:all without -a misleadingly shows only partial ref tags on this file due to duplicate IFD blocks, worth keeping in mind if others report inconsistent repro results.) After opening the file in RapidRAW and exporting (tested with "Strip GPS" both ON and OFF — no difference in outcome), the exported JPEG has zero GPS tags, not even the refs: exiftool -a -G1 -s export.jpg | grep -i gps This lines up exactly with the root cause described in #1207 — once the image is opened in the editor, persist_exif_if_missing writes a .rrdata sidecar, and from that point on write_image_with_metadata takes the sidecar path for export, which has no GPS read logic at all (unlike the kamadak-exif / rawler paths). So the "Strip GPS" toggle has no effect once a sidecar exists — it's not being ignored, it's just not reached. Confirms this isn't camera- or format-specific — happy to test the fix in #1207 against this file if it'd help verification before merge. |
|
Thanks @Wakaba0815 — this is a really useful data point, especially the note about needing Your read of the root cause matches the fix: GPS reading is now lifted out of the three metadata-source branches (sidecar / kamadak-exif / rawler) and runs unconditionally at the end of Testing against your S22 Ultra file before merge would be very welcome. To build this branch: gh pr checkout 1207 # or: git clone -b fix/1165-gps-export-preserved https://github.com/Waynting/RapidRAW
npm install
npm start # runs the tauri dev buildThen repeat your exact repro: open the file in the editor (so the If you want to run the regression tests too: |
|
Tested PR #1207 against my S22 Ultra file (built from Repro steps: opened the file in the editor (so the Strip GPS off — full GPS block preserved: Confirmed via |
Summary
Fixes #1165. GPS EXIF (location data) was always being stripped on export, even with Remove location data turned off.
Root cause
write_image_with_metadatahas three branches for sourcing the original image's metadata: the.rrdatasidecar, kamadak-exif (JPEG/PNG), and rawler (RAW). Only the kamadak and rawler branches had GPS-reading code.Opening any image in the app triggers
persist_exif_if_missing(image_loader.rs:81), which writes the.rrdatasidecar. From then on the sidecar branch fires on every export — silently bypassing both GPS code paths. So in practicestrip_gps=falsedid nothing for any image you'd opened in the editor.Affects JPEG (as reported) and RAW (same mechanism, just less likely to be noticed).
Fix
GPS reading is orthogonal to the rest of the metadata sourcing. Lifted GPS reading out of the per-branch logic into two helpers and added a single tail call that runs unconditionally when
!strip_gps:The sidecar / kamadak / rawler branches now handle only the non-GPS metadata they always did. GPS is re-read from the source file rather than parsed back from the sidecar's display strings (lossy —
"40 deg 26' 12.345\""can't round-trip cleanly into the rationalslittle_exifneeds).Behavior table
keep_metadata=falseTests
Added two regression tests in
exif_processing::tests. No new dependencies —tempfile,image,little_exif,kamadak-exifare all already in the project.issue_1165_gps_preserved_when_sidecar_exists_and_strip_gps_false— reproduces the exact bug trigger (real GPS tags +.rrdatasidecar viapersist_exif_if_missing), asserts GPS lat/lon/alt are preserved in the exported bytes.issue_1165_gps_stripped_when_strip_gps_true— asserts the toggle still works.Both pass:
Also verified:
cargo fmt --checkclean on the filecargo clippy --lib --tests --no-deps— no new warnings introducedNotes
GPSAltitudeRef(above/below sea-level reference). The rawler branch already wrote it; added for symmetry. Harmless if downstream readers don't expect it.get_string_valclosure is now defined in two places (the helper + the inline kamadak branch). Kept this PR narrow; happy to lift it to a module-level helper in a follow-up if you'd like.Test plan
cargo test --lib exif_processing::testscargo fmt -- --check src/exif_processing.rscargo clippy --lib --tests --no-depsexiftool -GPS:all exported.jpgshows coords